package com.henry.base.concurrency.test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ClientPut {
    static final int threadNum=4;

    public static void main(String[] args) throws InterruptedException {
        int capacity = 6000000;
        testArray(capacity);    //put in ArrayBlockingQueue size:=1000000,use time:=624
//        testLinked(capacity);    //put in LinkedBlockingQueue size:=1000000,use time:=289
        testConcurrentLinked(); //put in ConcurrentLinkedQueue size:=1000000,use time:=287

    }

    private static void testArray(int capacity) throws InterruptedException {
        ArrayBlockingQueue<Bread> queue = new ArrayBlockingQueue<Bread>(capacity);
        CountDownLatch cdl = new CountDownLatch(threadNum);
        ExecutorService es = Executors.newFixedThreadPool(threadNum);
        long start = System.currentTimeMillis();
        for(int i = 0; i < threadNum;i++) {
            es.submit(new ProducerArray(queue, cdl));
        }
        cdl.await();
        long end = System.currentTimeMillis();
        es.shutdown();
        System.out.println("put in ArrayBlockingQueue size:="+queue.size() +",use time:="+(end-start));
    }

    private static void testLinked(int capacity) throws InterruptedException {
        LinkedBlockingQueue<Bread> queue = new LinkedBlockingQueue<Bread>(capacity);
        CountDownLatch cdl = new CountDownLatch(threadNum);
        ExecutorService es = Executors.newFixedThreadPool(threadNum);
        long start = System.currentTimeMillis();
        for(int i = 0; i < threadNum;i++) {
            es.submit(new ProducerLinked(queue, cdl));
        }
        cdl.await();
        long end = System.currentTimeMillis();
        es.shutdown();
        System.out.println("put in LinkedBlockingQueue size:="+queue.size() +",use time:="+(end-start));
    }

    private static void testConcurrentLinked() throws InterruptedException {
        ConcurrentLinkedQueue<Bread> queue = new ConcurrentLinkedQueue<Bread>();
        CountDownLatch cdl = new CountDownLatch(threadNum);
        ExecutorService es = Executors.newFixedThreadPool(threadNum);
        long start = System.currentTimeMillis();
        for(int i = 0; i < threadNum;i++) {
            es.submit(new ProducerConcurrnetLinkedQueue(queue, cdl));
        }
        cdl.await();
        long end = System.currentTimeMillis();
        es.shutdown();
        System.out.println("put in ConcurrentLinkedQueue size:="+queue.size() +",use time:="+(end-start));
    }

}